﻿using System.Drawing;
using System.Windows.Forms;
using CloudShot.Editor.CanvasFigures;
using CloudShot.Entities;
using CloudShot.Interfaces;
using CloudShot.Properties;
using CloudShot.Utils;

namespace CloudShot.Editor.Tools
{
  internal sealed class CropTool : ObjectTool
  {
    private readonly IOpenWindowsService _openWindowsService;
    private readonly Section _createCropSection;
    private readonly Section _changeToolsSection;

    private readonly HighlightRectangle _highlightRectangle = new HighlightRectangle
    {
      BorderColor = Color.LawnGreen,
      BorderWidth = 3
    };

    private bool _isMouseDown;
    private bool _selectionMoveEnabled;
    private Point _rightBottomPoint;

    public CropTool(IDrawingCanvas drawingCanvas, IOpenWindowsService openWindowsService, Section createCropSection, Section changeToolsSection, Cursor cursor)
      : base(drawingCanvas, null, null, cursor)
    {
      _openWindowsService = openWindowsService;
      _createCropSection = createCropSection;
      _changeToolsSection = changeToolsSection;
      Canvas.GraphicsList.Add(_highlightRectangle);
    }

    public override void OnMouseDown(MouseEventArgs e)
    {
      Canvas.HideHint();
      Canvas.ShowHint(HintResources.CropTool_Sizing);
      _isMouseDown = true;
    }

    public override void OnMouseMove(MouseEventArgs e)
    {
      Rectangle rect = _isMouseDown ? Rectangle.Empty : GetWindowRectangle(Canvas.PointToScreen(e.Location));

      if (rect != _highlightRectangle.GetBoundingBox())
      {
        using (new AutomaticCanvasRefresher(Canvas, () => _highlightRectangle.GetBoundingBox()))
        {
          //NOTE: btw, empty rectangles is not will be painted
          _highlightRectangle.Rectangle = rect;//TODO: add animation here
        }
      }

      CanvasCrop crop = Canvas.Crop;

      using (new AutomaticCanvasRefresher(Canvas, crop.GetBoundingBox))
      {
        if (crop.IsSelectionState && e.Button == MouseButtons.None)
        {
          crop.IsSelectionState = true;

          int dx = e.X - crop.Rectangle.X;
          int dy = e.Y - crop.Rectangle.Y;

          crop.Move(dx, dy);
        }

        if (e.Button == MouseButtons.Left)
        {
          if (_selectionMoveEnabled)
          {
            int dx = e.X - _rightBottomPoint.X;
            int dy = e.Y - _rightBottomPoint.Y;

            _rightBottomPoint.X = e.X;
            _rightBottomPoint.Y = e.Y;

            crop.Move(dx, dy);
          }
          else
          {
            crop.MoveHandleTo(new Point(e.X, e.Y), VertexType.RightBottom, Canvas.IsAnyModifierPressed(KeyModifiers.Shift));
          }
        }
      }
    }

    public override void OnMouseUp(MouseEventArgs e)
    {
      _isMouseDown = false;

      using (new AutomaticCanvasRefresher(Canvas, () => _highlightRectangle.GetBoundingBox()))
      {
        Canvas.GraphicsList.Remove(_highlightRectangle);
      }

      CanvasCrop crop = Canvas.Crop;

      using (new AutomaticCanvasRefresher(Canvas, crop.GetBoundingBox))
      {
        if (crop.Rectangle.Location == e.Location && crop.Rectangle.Size.IsEmpty)
          crop.Rectangle = _highlightRectangle.Rectangle;
        
        //It is prohibited to create crop smaller than EditorTheme.MinimumFigureSize by one of it's side
        crop.Rectangle = crop.Rectangle.AdjustMinimalRect(EditorTheme.DefaultCropSize.Width, EditorTheme.DefaultCropSize.Height);

        crop.Normalize();
        crop.IsSelected = true;
        crop.IsSelectionState = false;
        crop.IsShowSize = false;       
        Canvas.CaptureMouse = false;
      }
    }

    public override void OnKeyDown(KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Space && !_selectionMoveEnabled)
      {
        var rect = Canvas.Crop.Rectangle;
        _rightBottomPoint.X = rect.Right;
        _rightBottomPoint.Y = rect.Bottom;

        _selectionMoveEnabled = true;
      }
    }

    public override void OnKeyUp(KeyEventArgs e)
    {
      _selectionMoveEnabled = false;
    }

    public override void Enter()
    {
      Canvas.ShowHint(HintResources.CropTool_Start);
      _createCropSection.Enabled = true;
    }

    public override void Leave()
    {
      Canvas.HideHint();
      _createCropSection.Enabled = false;
      _changeToolsSection.Enabled = true;
    }

    private Rectangle GetWindowRectangle(Point location)
    {
      WindowInfo window = _openWindowsService.GetWindowRectFromPoint(location, true);
      return window.ClientBounds;
    }
  }
}